
#include <unistd.h>
#include "tp_typedef.h"
#include "tp_pipe.h"

typedef struct _PrivInfo
{
	int write_fd;
	int read_fd;
}PrivInfo;

static int tp_pipe_linux_read(TpPipe* thiz, void* buffer, size_t len)
{
    int ret = 0;
    DECL_PRIV(thiz, priv);

    ret = read(priv->read_fd, buffer, len);

    return ret > 0 ? ret : 0;
}

static int tp_pipe_linux_write(TpPipe* thiz, void* data, size_t size)
{
    int ret = 0;
    DECL_PRIV(thiz, priv);

    ret = write(priv->write_fd, data, size);

    return ret > 0 ? ret : 0;
}

static int tp_pipe_linux_get_read_fd(TpPipe* thiz)
{
    DECL_PRIV(thiz, priv);

    return NULL != priv ? priv->read_fd : -1;
}

static int tp_pipe_linux_get_write_fd(TpPipe* thiz)
{
    DECL_PRIV(thiz, priv);

    return NULL != priv ? priv->write_fd : -1;
}

static void tp_pipe_linux_destroy(TpPipe* thiz)
{
    DECL_PRIV(thiz, priv);
	if (NULL != priv)
	{
        close(priv->read_fd);
		close(priv->write_fd);

		tp_free(thiz);
	}

	return;
}

TpPipe* tp_pipe_create(void)
{
	TpPipe* thiz = NULL;
	int pipes[2] = {-1};

	thiz = (TpPipe*)tp_alloc(sizeof(TpPipe) + sizeof(PrivInfo));
	if(NULL != thiz)
	{
		DECL_PRIV(thiz, priv);

		if(pipe(pipes) == 0)
		{
			priv->read_fd = pipes[0];
			priv->write_fd = pipes[1];

			thiz->read = tp_pipe_linux_read;
			thiz->write = tp_pipe_linux_write;
			thiz->get_read_fd = tp_pipe_linux_get_read_fd;
			thiz->get_write_fd = tp_pipe_linux_get_write_fd;
			thiz->destroy = tp_pipe_linux_destroy;
		}
		else
		{
			tp_free(thiz);
			thiz = NULL;
		}
	}

	return thiz;
}